package com.liuyjy.es.service;

import com.liuyjy.core.entity.PageResult;
import com.liuyjy.core.exception.EsException;
import com.liuyjy.es.model.req.AggregationCondition;
import com.liuyjy.es.model.req.GeoCondition;
import com.liuyjy.es.model.req.QueryCondition;
import com.liuyjy.es.wrapper.EsLambdaQueryWrapper;
import com.liuyjy.es.wrapper.EsLambdaUpdateWrapper;
import com.liuyjy.es.wrapper.EsQueryWrapper;
import com.liuyjy.es.wrapper.EsUpdateWrapper;
import org.elasticsearch.client.Cancellable;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @Author liuyjy
 * @Date 2025/2/24 13:00
 * @Description: 核心Service实现
 **/
public interface EsService {
    /**
     * 创建索引
     *
     * @param clazz 实体类
     * @param <T>   T
     * @return boolean
     */
    <T> boolean createIndex(Class<T> clazz);

    /**
     * 创建索引
     *
     * @param indexName 索引名称
     * @return boolean
     */
    boolean createIndex(String indexName);

    /**
     * 创建一个新的索引
     *
     * @param indexName 索引的名称
     * @param settings  索引的设置，如分片和副本的数量等
     * @param mappings  索引的映射，定义字段的类型
     * @return 如果索引创建成功返回true，否则返回false
     * <p>
     * 此方法负责向Elasticsearch集群发送创建索引的请求
     * 它允许在创建时指定索引的设置和映射，以满足特定的需求
     * 如果在创建过程中遇到IO异常，将抛出自定义的EsException异常
     */
    boolean createIndex(String indexName, Map<String, Object> settings, Map<String, Object> mappings);

    /**
     * 更新索引
     *
     * @param indexName 索引名称
     * @param mapping   映射信息
     * @return boolean
     */
    boolean updateMapping(String indexName, Map<String, Object> mapping);

    /**
     * 更新索引设置
     *
     * @param indexName 索引名称
     * @param settings  索引设置
     * @return boolean
     */
    boolean updateSetting(String indexName, Map<String, Object> settings);

    /**
     * 删除索引
     *
     * @param clazz 实体类
     * @param <T>   T
     * @return boolean
     */
    <T> boolean deleteIndex(Class<T> clazz);

    /**
     * 判断索引是否存在
     *
     * @param clazz 实体类
     * @param <T>   T
     * @return boolean
     */
    <T> boolean indexExists(Class<T> clazz);

    /**
     * 删除索引
     *
     * @param indexName 索引名称
     * @return boolean
     */
    boolean deleteIndex(String indexName);

    /**
     * 清空指定索引中的所有文档
     * 此方法通过删除查询来清空索引，它使用了一个匹配所有文档的查询
     * 如果操作成功，返回true；如果失败，抛出自定义异常
     *
     * @param clazz 实体类
     * @return 如果有文档被删除成功，则返回true，否则返回false
     * @throws EsException 如果清空索引失败，则抛出此异常
     */
    <T> boolean clearIndex(Class<T> clazz);

    /**
     * 清空指定索引中的所有文档
     * 此方法通过删除查询来清空索引，它使用了一个匹配所有文档的查询
     * 如果操作成功，返回true；如果失败，抛出自定义异常
     *
     * @param indexName 要清空的索引名称
     * @return 如果有文档被删除成功，则返回true，否则返回false
     * @throws EsException 如果清空索引失败，则抛出此异常
     */
    boolean clearIndex(String indexName);

    boolean indexExists(String indexName);

    // 查询
    // 查询功能
    <T> T getById(String indexName, String id, Class<T> clazz);

    /**
     * 检查指定索引中是否存在具有指定ID的文档
     *
     * @param indexName 索引名称，对应于存储文档的容器
     * @param id        文档的唯一标识符
     * @return 如果文档存在则返回true，否则返回false
     * <p>
     * 此方法使用GetRequest对象来查询Elasticsearch客户端，以检查指定索引中是否存在具有给定ID的文档
     * 当存在IO异常时，会抛出自定义的EsException异常，以通知调用者查询失败
     */
    boolean exists(String indexName, String id);

    <T> List<T> list(EsQueryWrapper<T> wrapper);

    <T> List<T> list(EsLambdaQueryWrapper<T> wrapper);

    <T> PageResult<T> page(EsQueryWrapper<T> wrapper);

    <T> PageResult<T> page(EsLambdaQueryWrapper<T> wrapper);

    /**
     * 聚合查询
     *
     * @param wrapper   条件
     * @param <T>       t
     * @return Map
     */
    <T> Map<String, Object> aggregate(EsQueryWrapper<T> wrapper);
    /**
     * 聚合查询
     *
     * @param wrapper   条件
     * @param <T>       t
     * @return Map
     */
    <T> Map<String, Object> aggregate(EsLambdaQueryWrapper<T> wrapper);

    Map<String, Object> aggregate(String indexName, AggregationCondition condition);

    // 文档操作
    <T> boolean save(T entity);

    <T> boolean save(String indexName, String id, T entity);

    <T> boolean save(String indexName, T entity);

    // 文档操作
    <T> Cancellable saveAsync(T entity);

    <T> Cancellable saveAsync(String indexName, String id, T entity);

    <T> Cancellable saveAsync(String indexName, T entity);

    <T> void saveBatch(Collection<T> entities);

    <T> void saveBatch(String indexName, Collection<T> entities);


    <T> boolean updateById(String indexName, String id, T entity);

    <T> boolean updateById(T entity);

    <T> void updateBatch(Collection<T> entities);

    <T> void updateBatch(String indexName, Collection<T> entities);

    <T> Cancellable updateByIdAsync(String indexName, String id, T entity);

    <T> Cancellable updateByIdAsync(T entity);

    <T> long updateByQuery(EsUpdateWrapper<T> wrapper);

    <T> long updateByQuery(EsLambdaUpdateWrapper<T> wrapper);

    <T> Cancellable updateByQueryAsync(EsUpdateWrapper<T> wrapper);

    <T> Cancellable updateByQueryAsync(EsLambdaUpdateWrapper<T> wrapper);

    boolean deleteById(String indexName, String id);

    Cancellable deleteByIdAsync(String indexName, String id);

    <T> long deleteByQuery(EsUpdateWrapper<T> wrapper);

    <T> long deleteByQuery(EsLambdaUpdateWrapper<T> wrapper);

    <T> Cancellable deleteByQueryAsync(EsUpdateWrapper<T> wrapper);

    <T> Cancellable deleteByQueryAsync(EsLambdaUpdateWrapper<T> wrapper);




    <T> List<T> searchList(String[] indices, QueryCondition condition, Class<T> clazz);

    <T> PageResult<T> searchPage(String[] indices, QueryCondition condition, Class<T> clazz);

    // 高级功能
    <T> List<T> geoSearch(String indexName, GeoCondition condition, Class<T> clazz);




    //boolean reindex(String sourceIndex, String destIndex);


}
